/************************************************************************

								Heroes IV
					  Copyright 2001, The 3DO Company

	------------------------------------------------------------------
  							linkage_data.cpp

	$Header: $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "linkage_data.h"

#include "adventure_map.h"
#include "link_type.h"
#include "player.h"
#include "player_color.h"
#include "town.h"
#include "town_type.h"

namespace
{
	int const k_current_no_town_map_version = 0;
	int const k_current_town_map_version = 0;
} // Unnamed namespace

// ------------------------------------------------------------------------------
// town type enumeration to link type enumeration
// Static member function
// ------------------------------------------------------------------------------
t_linkage_data::t_link_alignment t_linkage_data::town_type_to_link_alignment( t_town_type town_type )
{
	switch( town_type )
	{
		case k_town_life:
			return t_linkage_data::k_link_alignment_life;

		case k_town_order:
			return t_linkage_data::k_link_alignment_order;

		case k_town_death:
			return t_linkage_data::k_link_alignment_death;

		case k_town_chaos:
			return t_linkage_data::k_link_alignment_chaos;

		case k_town_nature:
			return t_linkage_data::k_link_alignment_nature;

		case k_town_might:
			return t_linkage_data::k_link_alignment_might;
	}

	return t_linkage_data::k_link_alignment_any;
}

// ------------------------------------------------------------------------------
// link type enumeration to town type enumeration
// Static member function
// ------------------------------------------------------------------------------
t_town_type t_linkage_data::link_alignment_to_town_type( t_link_alignment link_type )
{
	switch( link_type )
	{
		case k_link_alignment_life:
			return k_town_life;

		case k_link_alignment_order:
			return k_town_order;

		case k_link_alignment_death:
			return k_town_death;
		
		case k_link_alignment_chaos:
			return k_town_chaos;
		
		case k_link_alignment_nature:
			return k_town_nature;
		
		case k_link_alignment_might:
			return k_town_might;
	}

	return k_town_none;
}


// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
t_linkage_data::t_linkage_data( bool allow_towns )
	: m_allow_towns( allow_towns )
{
	reset();
}

// ------------------------------------------------------------------------------
// Return the alignment of the thing we are linked to
// ------------------------------------------------------------------------------
t_linkage_data::t_link_alignment t_linkage_data::get_link_alignment( t_adventure_map & map, int pass ) const
{
	switch( m_type )
	{
		case k_link_type_none:
			return k_link_alignment_any;

		case k_link_type_player:
			t_player *player;
			
			player = map.get_player( m_player_color );
			if ( player == NULL )
				return k_link_alignment_any;

			return town_type_to_link_alignment( player->get_alignment() );

		case k_link_type_town:
			if ( pass == 0 )
				return k_link_alignment_wait;

			t_town const * town = map.get_mapped_town( m_town_name );

			if ( town )
			{
				t_town_type town_type = town->get_type();

				if (    town_type == k_town_none 
					 || town_type >= k_town_type_count)
				{
					return k_link_alignment_any;
				}
				else
				{
					return town_type_to_link_alignment( town_type );
				}
			}
			break;
	}

	return k_link_alignment_any;
}

// ------------------------------------------------------------------------------
// Read data from map editor map file
// ------------------------------------------------------------------------------
bool t_linkage_data::read_from_map( std::streambuf & stream )
{
	int version = get< t_uint16 >( stream );
	int no_town_version;

	if (m_allow_towns)
	{
		if ( version < 0 || version > k_current_town_map_version)
			return false;

		// Translate version to no_town_version
		if (version >= 0)
			no_town_version = 0;
	}
	else
	{
		if ( version < 0 || version > k_current_no_town_map_version)
			return false;

		no_town_version = version;
	}

	std::string keyword;
	
	if (!::read_string16( stream, keyword ))
		return false;

	m_type = ::get_link_type( keyword );

	switch( m_type )
	{
		case k_link_type_none:
			m_player_color = k_player_gray;
			m_town_name.erase();
			break;

		case k_link_type_player:
			m_player_color = t_player_color( get< t_uint8 >( stream ) );
			m_town_name.erase();
			break;

		case k_link_type_town:
			if (!m_allow_towns)
				return false;

			m_player_color = k_player_gray;
			
			if (!::read_string16( stream, m_town_name ) )
				return false;

			break;
	}

	return true;
}

// ------------------------------------------------------------------------------
// Reset all members to their defaults
// ------------------------------------------------------------------------------
void t_linkage_data::reset()
{
	m_type = k_link_type_none;
	m_town_name.erase();
	m_player_color = k_player_gray;
}
